// Copyright (C) 1953-2023 NUDT
// Verilog module name - endB_traffic_generate 
// Version: V4.3.0.20230901
// Created:
//         by - fenglin 
////////////////////////////////////////////////////////////////////////////
// Description:
///////////////////////////////////////////////////////////////////////////
`timescale 1ns/1ps
module endB_traffic_generate(
input                 i_clk,
input                 i_rst_n,
input                 i_teststart_en,
input      [79:0]     iv_localclk,
input      [8:0]      iv_data,
input                 i_data_wr, 

output reg [8:0]      ov_data ,  
output reg            o_data_wr,
output reg            o_pktout_pulse
);         

reg       [10:0]       rv_rev_cycle_cnt;
reg       [7:0]        rv_send_cycle_cnt;
reg       [31:0]       rv_flowB_send_counter;
reg       [79:0]       rv_syn_sendtime;

reg       [377:0]      rv_pkt_data;

always@(posedge i_clk or negedge i_rst_n)begin 
    if(!i_rst_n) begin
		rv_pkt_data       <=378'd0;
		rv_rev_cycle_cnt  <=11'd0;
    end
    else begin	
		if(i_data_wr==1'b1)begin
			rv_pkt_data      <= {rv_pkt_data[368:0],iv_data};
			rv_rev_cycle_cnt <= rv_rev_cycle_cnt +1'b1;  
			
		end	
		else begin
			rv_pkt_data      <= {rv_pkt_data[368:0],9'b0};
			rv_rev_cycle_cnt <=11'd0;		
		end
    end       
end	

reg       [2:0]     btg_state;
localparam          INIT_S         = 3'd0,
					IDLE_S         = 3'd1,
					SEND_TCPHEAD_S = 3'd2,
					TNC_PKTLOAD_S  = 3'd3,
                    PKTFLAG_S      = 3'd4;

always@(posedge i_clk or negedge i_rst_n)begin 
    if(!i_rst_n) begin
		 o_data_wr          <=1'b0;
		 ov_data            <=9'd0;
		 o_pktout_pulse     <=1'b0;
         rv_send_cycle_cnt  <=8'd0;
		 rv_syn_sendtime    <=80'd0;
		 rv_flowB_send_counter         <=32'd0;
         btg_state          <=INIT_S;
    end
    else begin
        case(btg_state)
        INIT_S:begin  
			 o_data_wr            <=1'd0;
			 ov_data              <=9'd0;
			 rv_send_cycle_cnt    <=8'd0;
			 rv_syn_sendtime      <=80'd0;
			 rv_flowB_send_counter           <=32'd0;
			if(i_teststart_en==1'b1)begin          				
				btg_state <=IDLE_S;
            end			
            else begin				             
				btg_state <=INIT_S;
            end
        end		
        IDLE_S:begin  		
			if(i_teststart_en==1'b1)begin
				if((rv_rev_cycle_cnt==11'd16)&&({rv_pkt_data[25:18],rv_pkt_data[16:9],rv_pkt_data[7:0]}==24'h010501))begin //时间通告帧类型      				
					rv_send_cycle_cnt <= rv_send_cycle_cnt +1'b1;
					rv_flowB_send_counter  <= rv_flowB_send_counter +1'b1;
					rv_syn_sendtime   <= iv_localclk;
					o_pktout_pulse    <=1'd1;
					o_data_wr         <=1'd1;
					ov_data           <={1'b1,8'hbb};//流量B首字节	
					btg_state         <=SEND_TCPHEAD_S;	
				end
				else begin
					rv_send_cycle_cnt <= 8'd0;
					rv_flowB_send_counter  <= rv_flowB_send_counter;
					rv_syn_sendtime   <= 80'd0;
					o_data_wr         <= 1'd0;
					ov_data           <= 9'd0;
					o_pktout_pulse    <=1'd0;
					btg_state         <= IDLE_S;	
				end
			end			
            else begin				             
				o_data_wr        <= 1'd0;
				ov_data          <= 9'd0;
				rv_syn_sendtime  <= 80'd0;
				rv_flowB_send_counter <= 32'd0;
				rv_send_cycle_cnt<= 8'd0;
				o_pktout_pulse   <=1'd0;
				btg_state        <= INIT_S;
            end
        end
        SEND_TCPHEAD_S:begin 
			o_pktout_pulse    <=1'd0;
			rv_send_cycle_cnt         <= rv_send_cycle_cnt + 1'b1;
			rv_syn_sendtime           <= rv_syn_sendtime;			
			o_data_wr                 <= 1'b1;			
			case(rv_send_cycle_cnt)
				//dmac
				8'd1:ov_data          <= {1'b0,8'h00};
				8'd2:ov_data          <= {1'b0,8'h00};
				8'd3:ov_data          <= {1'b0,8'h00};
				8'd4:ov_data          <= {1'b0,8'h00};
				8'd5:ov_data          <= {1'b0,8'h03};
				//smac                
				8'd6:ov_data          <= {1'b0,8'hdd};
				8'd7:ov_data          <= {1'b0,8'h00};
				8'd8:ov_data          <= {1'b0,8'h00};
				8'd9:ov_data          <= {1'b0,8'h00};
				8'd10:ov_data         <= {1'b0,8'h00};
				8'd11:ov_data         <= {1'b0,8'h01};
				//eth type
				8'd12:ov_data         <= {1'b0,8'h08};
				8'd13:ov_data         <= {1'b0,8'h00};	
				8'd14:ov_data         <= {1'b0,8'h45};
				8'd15:ov_data         <= {1'b0,8'h00};
				8'd16:ov_data         <= {1'b0,8'h00};
				8'd17:ov_data         <= {1'b0,8'h60};
				8'd18:ov_data         <= {1'b0,8'h79};
				8'd19:ov_data         <= {1'b0,8'h19};
				8'd20:ov_data         <= {1'b0,8'h00};
				8'd21:ov_data         <= {1'b0,8'h00};
				8'd22:ov_data         <= {1'b0,8'h40};
				//protocol
				8'd23:ov_data         <= {1'b0,8'h06};
				8'd24:ov_data         <= {1'b0,8'h7e};
				8'd25:ov_data         <= {1'b0,8'h2a};
				//src ip
				8'd26:ov_data         <= {1'b0,8'hC0};
				8'd27:ov_data         <= {1'b0,8'hA8};
				8'd28:ov_data         <= {1'b0,8'h01};
				8'd29:ov_data         <= {1'b0,8'h03};
				//dst ip
				8'd30:ov_data         <= {1'b0,8'hC0};
				8'd31:ov_data         <= {1'b0,8'hA8};
				8'd32:ov_data         <= {1'b0,8'h01};
				8'd33:ov_data         <= {1'b0,8'h01};
				//source port
				8'd34:ov_data         <= {1'b0,8'h15};
				8'd35:ov_data         <= {1'b0,8'hB3};
				//dest port
				8'd36:ov_data         <= {1'b0,8'h1A};
				8'd37:ov_data         <= {1'b0,8'h0A};
				8'd38:begin
					ov_data           <= rv_pkt_data[377:369];
					btg_state         <= TNC_PKTLOAD_S;
				end  
				default:begin
					ov_data           <= 9'd0;
					btg_state         <=IDLE_S;	
				end 				
			endcase
        end	      
       TNC_PKTLOAD_S:begin 
			rv_send_cycle_cnt     <= rv_send_cycle_cnt + 1'b1;				
			o_data_wr             <= 1'b1;
			if(rv_pkt_data[377]!=1'b1)begin
				ov_data           <= rv_pkt_data[377:369];
				btg_state         <= TNC_PKTLOAD_S;
			end
			else begin 
				ov_data           <= {1'b0,rv_pkt_data[376:369]};
				btg_state         <= PKTFLAG_S;				
			end		
		end	
       PKTFLAG_S:begin 
			rv_send_cycle_cnt    <= rv_send_cycle_cnt + 1'b1;				
			o_data_wr            <= 1'b1;			
			case(rv_send_cycle_cnt)
				8'd86:ov_data    <= {1'b0,8'h00 };
				8'd87:ov_data    <= {1'b0,8'h00 };
				8'd88:ov_data    <= {1'b0,8'h00 };
				8'd89:ov_data    <= {1'b0,rv_flowB_send_counter[31:24] };
				8'd90:ov_data    <= {1'b0,rv_flowB_send_counter[23:16]  };
				8'd91:ov_data    <= {1'b0,rv_flowB_send_counter[15:8] };					
				8'd92:ov_data    <= {1'b0,rv_flowB_send_counter[7:0]  };
				8'd93:ov_data    <= {1'b0,rv_syn_sendtime[79:72]};
				8'd94:ov_data    <= {1'b0,rv_syn_sendtime[71:64]};
				8'd95:ov_data    <= {1'b0,rv_syn_sendtime[63:56]};
				8'd96:ov_data    <= {1'b0,rv_syn_sendtime[55:48]};
				8'd97:ov_data    <= {1'b0,rv_syn_sendtime[47:40]};
				8'd98:ov_data    <= {1'b0,rv_syn_sendtime[39:32]};
				8'd99:ov_data    <= {1'b0,rv_syn_sendtime[31:24]};
				8'd100:ov_data   <= {1'b0,rv_syn_sendtime[23:16]};
				8'd101:ov_data   <= {1'b0,rv_syn_sendtime[15:8]};
				8'd102:begin
					ov_data      <= {1'b1,rv_syn_sendtime[7:0]};
					btg_state          <= IDLE_S;
				end  
				default:begin
					ov_data           <= 9'd0;
					btg_state          <=IDLE_S;	
				end 				
			endcase
        end	          		
        default:begin
			o_data_wr          <= 1'h0;
			ov_data            <= 9'd0;
            rv_send_cycle_cnt  <= 8'd0;
			rv_syn_sendtime    <= 80'd0;
			btg_state           <=IDLE_S;	
		end  
        endcase           
    end       
end
endmodule

/*
endB_traffic_generate endB_traffic_generate_inst(
.i_clk         ( ),
.i_rst_n       ( ),
.i_teststart_en( ),
.iv_localclk   ( ),
.iv_data       ( ),
.i_data_wr     ( ),
.ov_data       ( ),
.o_data_wr     ( ),
.o_pktout_pulse( )
);
*/